import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Post,
  Put,
  Query,
  UseGuards,
  Req,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { ApiOperation, ApiTags, ApiConsumes, ApiBody } from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileNameEncodePipe } from '~/common/pipes/file-name-encode.pipe';

import { ApiResult } from '~/common/decorators/api-result.decorator';
import { IdParam } from '~/common/decorators/id-param.decorator';

import { Pagination } from '~/helper/paginate/pagination';
import {
  definePermission,
  Perm,
} from '~/modules/auth/decorators/permission.decorator';
import { Resource } from '~/modules/auth/decorators/resource.decorator';

import { ResourceGuard } from '~/modules/auth/guards/resource.guard';
import { TodoEntity } from '~/modules/todo/todo.entity';

import {
  TodoDto,
  TodoQueryDto,
  TodoUpdateDto,
  FileUploadDto,
  FileDataSaveDto,
} from './todo.dto';
import { TodoService } from './todo.service';
import { OperationLog } from '../../common/decorators/log.decorator';

export const permissions = definePermission('todo', {
  LIST: 'list',
  CREATE: 'create',
  READ: 'read',
  UPDATE: 'update',
  DELETE: 'delete',
} as const);

@ApiTags('Business - Todo模块')
@UseGuards(ResourceGuard)
@Controller('todos')
export class TodoController {
  constructor(private readonly todoService: TodoService) {}

  // TODO导出
  @Get('excel-export')
  @ApiOperation({ summary: 'ToDo导出' })
  @OperationLog({
    module: 'ToDo',
    actionType: '导出todo',
  })
  async ExcelExport() {
    return this.todoService.excelExport();
  }

  //TODO-导入判断数据符不符合
  @Post('excel-import-check-data')
  @ApiOperation({ summary: 'ToDo导入数据验证' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    type: FileUploadDto,
  })
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(FileInterceptor('file'))
  @ApiBody({
    type: FileUploadDto,
  })
  async ExcelImportCheckData(
    @UploadedFile(new FileNameEncodePipe()) file: Express.Multer.File
  ) {
    return await this.todoService.ExcelImportCheckData(file);
  }

  // TODO导入 数据保存
  @Post('excel-import-sava-data')
  @ApiBody({
    type: FileDataSaveDto,
  })
  @ApiOperation({ summary: 'ToDo导入数据存储' })
  @OperationLog({
    module: 'ToDo',
    actionType: '导入todo',
  })
  async ExcelImportSaveData(@Body() body) {
    return await this.todoService.ExcelImportSaveData(body);
  }

  @Get()
  @ApiOperation({ summary: '获取Todo列表' })
  @ApiResult({ type: [TodoEntity] })
  @Perm(permissions.LIST)
  @OperationLog({
    module: 'ToDo',
    actionType: '获取详情',
  })
  async list(@Query() dto: TodoQueryDto): Promise<Pagination<TodoEntity>> {
    return this.todoService.list(dto);
  }

  @Get(':id')
  @ApiOperation({ summary: '获取Todo详情' })
  @ApiResult({ type: TodoEntity })
  @Perm(permissions.READ)
  @OperationLog({
    module: 'ToDo',
    actionType: '获取详情',
  })
  async info(@IdParam() id: number): Promise<TodoEntity> {
    return this.todoService.detail(id);
  }

  @Post()
  @ApiOperation({ summary: '创建Todo' })
  @Perm(permissions.CREATE)
  @OperationLog({
    module: 'ToDo',
    actionType: '创建todo',
  })
  async create(@Body() dto: TodoDto): Promise<void> {
    await this.todoService.create(dto);
  }

  @Put(':id')
  @ApiOperation({ summary: '更新Todo' })
  @Perm(permissions.UPDATE)
  @Resource(TodoEntity)
  @OperationLog({
    module: 'ToDo',
    actionType: '更新todo',
  })
  async update(
    @IdParam() id: number,
    @Body() dto: TodoUpdateDto
  ): Promise<void> {
    await this.todoService.update(id, dto);
  }

  @Delete(':id')
  @ApiOperation({ summary: '删除Todo' })
  @Perm(permissions.DELETE)
  @Resource(TodoEntity)
  @OperationLog({
    module: 'ToDo',
    actionType: '删除todo',
  })
  async delete(@IdParam() id: number): Promise<void> {
    await this.todoService.delete(id);
  }
}
